import {
  adapterUtils,
  IDCardUtils,
} from "../../../../utils/index.js";
import dayjs from "dayjs";
import customParseFormat from "dayjs/plugin/customParseFormat.js";
dayjs.extend(customParseFormat);

const { setPersonMessage } = adapterUtils;
const tizhiDic = {
  气虚质: "qixuzhi",
  气虚: "qixuzhi",
  阳虚质: "yangxuzhi",
  阳虚: "yangxuzhi",
  阴虚质: "yinxuzhi",
  阴虚: "yinxuzhi",
  痰湿质: "tanshizhi",
  痰湿: "tanshizhi",
  湿热质: "shirezhi",
  湿热: "shirezhi",
  血瘀质: "xueyuzhi",
  血瘀: "xueyuzhi",
  气郁质: "qiyuzhi",
  气郁: "qiyuzhi",
  特禀质: "tebingzhi",
  特禀: "tebingzhi",
  平和质: "pinghezhi",
  平和: "pinghezhi",
};

export function chineseMedicineAdapter(person) {
  person.NOTE = "";

  person.IDNum = IDCardUtils.formatIDNum(person.IDNum);
  if (!IDCardUtils.verifyIDNum(person.IDNum)) {
    return setPersonMessage(person, "身份证号码有误");
  }

  person.hztz = person.hztz.replace(/\s/g, "");
  const _person = { ...person };

  if (!person.physicalExaminer) {
    return setPersonMessage(person, "没有填写体检医生");
  }

  person.tddate = adapterUtils.formattedDate(person.tddate);
  if (
    dayjs(person.tddate, [
      "YYYYMMDD",
      "YYYY-MM-DD HH:mm:ss",
      "YYYY-MM-DD",
      "YYYY.M.D",
      "YYYY-M-D",
      "YYYY/M/D",
    ]).isValid()
  ) {
    person.tddate = dayjs(person.tddate, [
      "YYYYMMDD",
      "YYYY-MM-DD HH:mm:ss",
      "YYYY-MM-DD",
      "YYYY.M.D",
      "YYYY-M-D",
      "YYYY/M/D",
    ]).format("YYYY-MM-DD");
  } else {
    return setPersonMessage(person, "建档日期格式错误");
  }

  autoCalculateScore({ _person, person });
  person.sum = newConstitutionScore(person);
  person.constitutionType = constitutionCalculate(person);
  if (isAllZero(person.constitutionType)) {
    return setPersonMessage(person, "没有找到对应体质");
  }

  return person;
}

function init9and28({ _person, person } = {}) {
  if (!person.hztz) {
    return setPersonMessage(person, "没有填写体质类型，无法倒推");
  }

  // console.log('Number.isNaN(+_person[9]', Number.isNaN(+_person[9]));
  // 第九题，BMI
  if (Number.isNaN(+_person[9])) {
    if (_person[9]) {
      if (_person[9].includes("＜24")) person[9] = 1;
      if (_person[9].includes("＜25")) person[9] = 2;
      if (_person[9].includes("＜26")) person[9] = 3;
      if (_person[9].includes("＜28")) person[9] = 4;
      if (_person[9].includes("≥28")) person[9] = 5;
    }
  } else {
    // > 5，则是BMI值
    const num = +_person[9];
    if (num > 5) {
      if (num < 24) person[9] = 1;
      else if (num < 25) person[9] = 2;
      else if (num < 26) person[9] = 3;
      else if (num < 28) person[9] = 4;
      else if (num >= 28) person[9] = 5;
    } else {
      person[9] = Math.floor(num);
    }
  }

  // 第28题，腹围
  if (Number.isNaN(+_person[28])) {
    if (_person[28]) {
      if (_person[28].includes("<80")) person[28] = 1;
      if (_person[28].includes("80-85")) person[28] = 2;
      if (_person[28].includes("86-90")) person[28] = 3;
      if (_person[28].includes("91-105")) person[28] = 4;
      if (_person[28].includes(">105")) person[28] = 5;
    }
  } else {
    // > 5，则是腰围值
    const num = +_person[28];
    if (num > 5) {
      if (num < 80) person[28] = 1;
      else if (num <= 85) person[28] = 2;
      else if (num <= 90) person[28] = 3;
      else if (num <= 105) person[28] = 4;
      else if (num > 105) person[28] = 5;
    } else {
      person[28] = Math.floor(num);
    }
  }

  // 如果9或28为空，并且体质不是痰湿质，那么9和28题总分最大为6。
  if ((!person[9] || !person[28]) && person.hztz.indexOf("痰湿") === -1) {
    person[9] = adapterUtils.getRandomNum(1, 4);
    person[28] = adapterUtils.getRandomNum(1, 6 - person[9]);
  }
}

function autoCalculateScore({ _person, person }) {
  init9and28({ _person, person });
  if (person.NOTE) return;

  const { hztz } = person;
  const tz = tizhiDic[hztz];
  if (!tz) {
    return setPersonMessage(person, "没有按格式填写体质");
  }

  if (!person[9]) person[9] = adapterUtils.getRandomNum(1, 5);
  if (!person[28]) person[28] = adapterUtils.getRandomNum(1, 5);
  // 大石：第一题，气虚质、阳虚质、阴虚质选2-3之间，平和质4-5;其他体质3-4
  if (["qixuzhi", "yangxuzhi", "yinxuzhi"].includes(tz))
    person[1] = adapterUtils.getRandomNum(2, 3);
  else if (tz === "pinghezhi") person[1] = 4;
  else person[1] = adapterUtils.getRandomNum(3, 4);

  // 石壁：第一题第二题不选1与5，第一题选2-3对应第二题的3-4，第一题的3-4对应第二题的2-3
  if (person[1] < 3) person[2] = adapterUtils.getRandomNum(3, 4);
  if (person[1] === 3) person[2] = adapterUtils.getRandomNum(2, 4);
  if (person[1] > 3) person[2] = adapterUtils.getRandomNum(2, 3);
  const tizhi = {
    qixuzhi: [3, 4, 14], // 2, 第二题根据第一题赋值
    yangxuzhi: [11, 12, 13, 29],
    yinxuzhi: [10, 21, 26, 31],
    tanshizhi: [16, 32], // 9, 28
    shirezhi: [23, 25, 27, 30],
    xueyuzhi: [19, 22, 24, 33],
    qiyuzhi: [5, 6, 7, 8],
    tebingzhi: [15, 17, 18, 20],
  };
  // 第二题不减少了（石壁）
  const pinghezhi = [4, 5, 13]; // 2,

  // 初始化33题为1分，第1题（只和平和质有关），第二题根据第一题变化，第9和28题（和痰湿质有关）除外
  for (let i = 3; i <= 33; i++) {
    if (person[9] && i === 9) continue;
    if (person[28] && i === 28) continue;
    person[i] = 1;
  }

  if (tz !== "pinghezhi") {
    // ![各种体质分数对照](https://gitee.com/k1ngbanana/image/raw/master/markdown/20210225102230.png)
    // ![第九题对应分数](https://gitee.com/k1ngbanana/image/raw/master/markdown/20210225102320.png)
    // ![第28题对应分数](https://gitee.com/k1ngbanana/image/raw/master/markdown/20210225102342.png)
    // 先生成体质的分数，题目分数和要 >= 11， 并且其他要 <= 8
    // 平和质 所有得分 <= 8， 1,2,4,5,13加起来 >= 17, 其中2,4,5,13反向计分，即(1->5, 2->4, ... 5->1)
    for (const key of Object.keys(tizhi)) {
      let tzScore;
      if (key === tz) {
        tzScore = adapterUtils.getRandomNum(11, 18);
      } else {
        tzScore = adapterUtils.getRandomNum(4, 8);
      }
      // console.log(tzScore, person[9], person[28]);
      // 减去初始化的分数
      if (key === "tanshizhi") tzScore -= person[9] + person[28] + 2;
      // 如果痰湿质的话，最大剩余的值只能是8，不然后面tzScore不可能减到0
      if (key === "tanshizhi" && tzScore > 8) tzScore = 8;
      // 有可能会小于0，不过不影响赋值，因为前面已经赋值了
      if (key !== "tanshizhi") tzScore -= 4;
      // 气虚质的话，将第二题的分数减去（石壁需求导致的）
      if (key === "qixuzhi") {
        tzScore -= person[2] - 1;
        // 因为气虚质剩下的值只能前去3*4 = 12，所以最大值重置12
        if (tzScore > 12) tzScore = 12;
      }

      // 开始循环，直到sore为0
      while (tzScore > 0) {
        for (const qIndex of tizhi[key]) {
          const temp = adapterUtils.getRandomNum(0, 1);
          if (person[qIndex] >= 5) continue;
          person[qIndex] += temp;
          tzScore -= temp;
          if (tzScore <= 0) break;
        }
      }
    }
  } else {
    // 平和质
    for (const key of Object.keys(tizhi)) {
      let tzScore = adapterUtils.getRandomNum(4, 8);
      // 减去初始化的分数
      // console.log(tzScore, person[9], person[28]);
      if (key === "tanshizhi") tzScore -= person[9] + person[28] + 2;
      else tzScore -= 4;
      // 气虚质的话，将第二题的分数减去（石壁需求导致的）
      if (key === "qixuzhi") tzScore -= person[2] - 1;

      // 有可能会小于0，不过不影响赋值，因为前面已经赋值了
      // 开始循环，直到sore为0
      while (tzScore > 0) {
        for (const qIndex of tizhi[key]) {
          if (person[qIndex] >= 5) continue;
          const temp = adapterUtils.getRandomNum(0, 1);
          person[qIndex] += temp;
          tzScore -= temp;
          if (tzScore <= 0) break;
        }
      }
    }
    // 上面算出所有体质都是小于8的，然后再减小2，4，5，13的值，就能增大平和质的值，增到到17-20之间的值就停止，第一题因为是正向几分，不变化了，简单点
    // 第二题不减少了（石壁）
    let tzScore =
      person[1] + 24 - (person[2] + person[4] + person[5] + person[13]);
    if (tzScore >= 17) return;
    // 计算要减小多少，才会使体质变成平和质
    tzScore = adapterUtils.getRandomNum(17, 20) - tzScore;
    while (tzScore > 0) {
      for (const qIndex of pinghezhi) {
        if (person[qIndex] === 1) continue;
        const temp = adapterUtils.getRandomNum(0, 1);
        person[qIndex] -= temp;
        tzScore -= temp;
        if (tzScore <= 0) break;
      }
    }
  }
}

// 倒推用体质得分计算
function newConstitutionScore(person) {
  const sum1 = person[2] + person[3] + person[4] + person[14];
  const sum2 = person[11] + person[12] + person[13] + person[29];
  const sum3 = person[10] + person[21] + person[26] + person[31];
  const sum4 = person[9] + person[16] + person[28] + person[32];
  const sum5 = person[23] + person[25] + person[27] + person[30];
  const sum6 = person[19] + person[22] + person[24] + person[33];
  const sum7 = person[5] + person[6] + person[7] + person[8];
  const sum8 = person[15] + person[17] + person[18] + person[20];
  const sum9 =
    person[1] + 24 - (person[2] + person[4] + person[5] + person[13]);
  return {
    sum1,
    sum2,
    sum3,
    sum4,
    sum5,
    sum6,
    sum7,
    sum8,
    sum9,
  };
}

/**
 * 体质辨识
 */
function constitutionCalculate(person) {
  const dic = {
    qixubianshi: "0",
    yangxubianshi: "0",
    yinxubianshi: "0",
    tanshibianshi: "0",
    shirebianshi: "0",
    xueyubianshi: "0",
    qiyubianshi: "0",
    tebingbianshi: "0",
    pinghebianshi: "0",
  };

  if (~person.hztz.indexOf("气虚")) {
    dic.qixubianshi = "1";
  }
  if (~person.hztz.indexOf("阳虚")) {
    dic.yangxubianshi = "1";
  }
  if (~person.hztz.indexOf("阴虚")) {
    dic.yinxubianshi = "1";
  }
  if (~person.hztz.indexOf("痰湿")) {
    dic.tanshibianshi = "1";
  } else if (person.sum.sum4 >= 11) {
    // 体质为其他的时候，sum4>8，为偏向痰湿质
    dic.tanshibianshi = "1";
    person.NOTE = `体质为${person.hztz}，但是痰湿质评分为11或以上，同时为两个体质，请核对`;
  } else if (person.sum.sum4 > 8) {
    dic.tanshibianshi = "2";
  }
  if (~person.hztz.indexOf("湿热")) {
    dic.shirebianshi = "1";
  }
  if (~person.hztz.indexOf("血瘀")) {
    dic.xueyubianshi = "1";
  }
  if (~person.hztz.indexOf("气郁")) {
    dic.qiyubianshi = "1";
  }
  if (~person.hztz.indexOf("特禀")) {
    dic.tebingbianshi = "1";
  }
  if (~person.hztz.indexOf("平和")) {
    if (person.sum.sum4 > 8) {
      dic.pinghebianshi = "2";
    } else {
      dic.pinghebianshi = "1";
    }
  }
  return dic;
}

function isAllZero(constitutionType) {
  let flag = true;
  for (const value of Object.values(constitutionType)) {
    if (value !== "0") flag = false;
  }
  return flag;
}
